(function() 
{
	function check( editor, wrapper ) 
	{
		var desiredHeight = getDesiredHeight(editor),
			currentHeight = editor.window.getViewPaneSize().height,
			newHeight = getEffectiveHeight( editor, desiredHeight );

  		if ( newHeight != currentHeight )
		{
			newHeight = editor.fire( 'beforeAutogrow' , {currentHeight : currentHeight, newHeight : newHeight} ).newHeight;
			
			wrapper.setStyle('height', newHeight + 'px');
			editor.fire( 'afterAutogrow' );
		}
	}

	function getEffectiveHeight( editor, height ) 
	{
		var min = editor.config.autogrowMinHeight,
			max = editor.config.autogrowMaxHeight;
		if ( min && min > height ) 
			height = min;
		else if ( max && max < height ) 
			height = max;
		return height;
	}

	function getDesiredHeight( editor ) 
	{
		var doc = editor.document.$,
			size;

		if ( CKEDITOR.env.ie )
			size = doc.documentElement.scrollHeight;
		else 
			size = doc.documentElement.offsetHeight;
		return size;
	}

	CKEDITOR.plugins.add( 'autogrow', {
		
		init : function( editor ) 
		{
			editor.on( 'mode', function( event )
			{
				event.removeListener();
				var wrapper = CKEDITOR.document.getById('cke_contents_' + editor.name);
				function listener () 
				{
					check(editor, wrapper);
				}

				editor.on('contentDom', listener);
				editor.on('key', listener);
				editor.on('selectionChange', listener);
				editor.on('insertElement', function() 
				{
					setTimeout(listener, 1000);
				});
			});
		}
	});

	/**
	 * Minimum height of an editor instance that uses the autogrow plugin
	 * @type Number
	 * @default 200
	 * @example
	 * config.autogrowMinHeight = 200;
	 */
	CKEDITOR.config.autogrowMinHeight = 200;

	/**
	 * Maximum height of an editor instance that uses the autogrow plugin
	 * @type Number
	 * @default 500
	 * @example
	 * config.autogrowMaxHeight = 500;
	 */
	CKEDITOR.config.autogrowMaxHeight = 500;
})();